package com.gitee.loyo.jdbc

import java.math.BigDecimal
import java.sql.Date
import java.sql.PreparedStatement
import java.sql.Time
import java.sql.Timestamp
import java.time.LocalDate
import java.time.LocalDateTime
import java.time.LocalTime

fun interface ParameterHandler<T> {

    fun handle(stmt: PreparedStatement, i: Int, parameter: T)

    companion object {
        val SHORT: ParameterHandler<Short> =
            ParameterHandler { stmt: PreparedStatement, i: Int, parameter: Short -> stmt.setShort(i, parameter)}
        val INT: ParameterHandler<Int> =
            ParameterHandler { stmt: PreparedStatement, i: Int, parameter: Int -> stmt.setInt(i, parameter) }
        val LONG: ParameterHandler<Long> =
            ParameterHandler { stmt: PreparedStatement, i: Int, parameter: Long -> stmt.setLong(i, parameter) }
        val FLOAT: ParameterHandler<Float> =
            ParameterHandler { stmt: PreparedStatement, i: Int, parameter: Float -> stmt.setFloat(i, parameter) }
        val DOUBLE: ParameterHandler<Double> =
            ParameterHandler { stmt: PreparedStatement, i: Int, parameter: Double -> stmt.setDouble(i, parameter) }
        val BOOLEAN: ParameterHandler<Boolean> =
            ParameterHandler { stmt: PreparedStatement, i: Int, parameter: Boolean -> stmt.setBoolean(i, parameter) }
        val STRING: ParameterHandler<String> =
            ParameterHandler { stmt: PreparedStatement, i: Int, parameter: String -> stmt.setString(i, parameter) }
        val DATE: ParameterHandler<java.util.Date> =
            ParameterHandler { stmt: PreparedStatement, i: Int, parameter: java.util.Date -> stmt.setTimestamp(i, Timestamp(parameter.time) ) }
        val LOCAL_DATE: ParameterHandler<LocalDate> =
            ParameterHandler { stmt: PreparedStatement, i: Int, parameter: LocalDate -> stmt.setDate(i, Date.valueOf(parameter) ) }
        val LOCAL_TIME: ParameterHandler<LocalTime> =
            ParameterHandler { stmt: PreparedStatement, i: Int, parameter: LocalTime -> stmt.setTime(i, Time.valueOf(parameter) ) }
        val LOCAL_DATE_TIME: ParameterHandler<LocalDateTime> =
            ParameterHandler { stmt: PreparedStatement, i: Int, parameter: LocalDateTime -> stmt.setTimestamp(i, Timestamp.valueOf(parameter)) }
        val BIG_DECIMAL: ParameterHandler<BigDecimal> =
            ParameterHandler { stmt: PreparedStatement, i: Int, parameter: BigDecimal -> stmt.setBigDecimal(i, parameter) }
        val BYTE_ARRAY: ParameterHandler<ByteArray> =
            ParameterHandler { stmt: PreparedStatement, i: Int, parameter: ByteArray -> stmt.setBytes(i, parameter) }
        val INT_ARRAY: ParameterHandler<Array<Int>> =
            ParameterHandler { stmt: PreparedStatement, i: Int, parameter: Array<Int> -> stmt.setArray(i, stmt.connection.createArrayOf("integer", parameter)) }
        val STRING_ARRAY: ParameterHandler<Array<String>> =
            ParameterHandler { stmt: PreparedStatement, i: Int, parameter: Array<String> -> stmt.setArray(i, stmt.connection.createArrayOf("varchar", parameter)) }
        val BIG_DECIMAL_ARRAY: ParameterHandler<Array<BigDecimal>> =
            ParameterHandler { stmt: PreparedStatement, i: Int, parameter: Array<BigDecimal> -> stmt.setArray(i, stmt.connection.createArrayOf("numeric", parameter)) }
    }
}